//---------------------------------------------------------------------
// Author: Keith Hill
//
// Description: Class to implement some generic error utilities.
//
// Creation Date: Sept 12, 2006
//---------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Management.Automation;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Security;
using System.Text;

using Pscx.Interop;

namespace Pscx
{
    static class Utils
    {
        public static void EnsureWindowsVista(PSCmdlet command)
        {
            OperatingSystem os = Environment.OSVersion;
            
            if((os.Platform != PlatformID.Win32NT) || (os.Version.Major < 6))
            {
                command.ThrowTerminatingError(new ErrorRecord(
                    new PlatformNotSupportedException("Microsoft Windows Vista or later required."),
                    "NotSupportedPlatform",
                    ErrorCategory.NotImplemented,
                    null));
            }
        }

        public static void AdjustTokenPrivileges(SafeTokenHandle hToken, TokenPrivilegeCollection privileges)
        {
            byte[] buffer = privileges.ToTOKEN_PRIVILEGES();
            if (!NativeMethods.AdjustTokenPrivileges(hToken,
                                                     false,
                                                     buffer,
                                                     buffer.Length,
                                                     IntPtr.Zero,
                                                     IntPtr.Zero))
            {
                throw PscxErrorRecord.LastWin32Exception();
            }
        }

        [Obsolete("Derive from PscxPathCommandBase instead.")]
        public static List<string> ResolveFilePaths(PSCmdlet psCmdlet, string[] pathsToResolve)
        {
            return ResolveFilePaths(psCmdlet, pathsToResolve, false);
        }
        
        [Obsolete("Derive from PscxPathCommandBase instead.")]
        public static List<string> ResolveFilePaths(PSCmdlet psCmdlet, string[] pathsToResolve, bool literalPaths)
        {
            List<string> pathList = new List<string>();
            foreach (string path in pathsToResolve)
            {
                if (literalPaths)
                {
                    // If literal path is used then don't use the API that expands wildcards
                    string urpath = psCmdlet.GetUnresolvedProviderPathFromPSPath(path);
                    pathList.Add(urpath);
                    psCmdlet.WriteDebug("Provider literal path is " + urpath);
                }
                else
                {
                    ProviderInfo providerInfo;
                    Collection<string> rpaths = psCmdlet.GetResolvedProviderPathFromPSPath(path, out providerInfo);
                    pathList.AddRange(rpaths);
                    for (int i = 0; i < Math.Min(20, rpaths.Count); i++)
                    {
                        psCmdlet.WriteDebug("Resolved provider path is " + rpaths[i]);
                    }
                    if (rpaths.Count > 20)
                    {
                        psCmdlet.WriteDebug("Resolved provider paths 20 .. " + rpaths.Count + " elided");
                    }
                }
            }
            return pathList;
        }
        
        [Obsolete("Use EncodingParameter and PscxCmdlet.ValidateEncoding() instead")]
        public static Encoding GetEncodingFromName(string encodingName)
        {
            Encoding e = EncodingParameter.EncodingFromName(encodingName);
            if(e == null) throw new ArgumentException();

            return e;
        }

        [Obsolete("Use EncodingParameter.ToEncoding(). Returns unicode encodings which do not output BOM")]
        public static byte[] RemoveByteOrderMark(MemoryStream input)
        {
            return input.ToArray();
        }

        public static T GetAttribute<T>(ICustomAttributeProvider provider)
            where T : Attribute
        {
            return GetAttribute<T>(provider, false);
        }

        public static T GetAttribute<T>(ICustomAttributeProvider provider, bool inherit)
            where T : Attribute
        {
            object[] attrs = provider.GetCustomAttributes(typeof(T), inherit);
            
            if(attrs == null || attrs.Length == 0)
            {
                return null;
            }

            return attrs[0] as T;
        }
    }
}